﻿using CSRedis;
using Newtonsoft.Json;
using System.ComponentModel;
using System.Globalization;
using System.Security.Cryptography.X509Certificates;

namespace CSRedisDemo
{
    internal class Program
    {
        public enum LastAlarm_AlarmStatus
        {
            /// <summary>
            /// 待受理
            /// </summary>
            [Description("待受理")]
            WaitingHandle = 0,

            /// <summary>
            /// 已通知
            /// </summary>
            [Description("已通知")]
            AlreadyNotice = 1,

            /// <summary>
            /// 已完成
            /// </summary>
            [Description("已完成")]
            HaveBeenDone = 2,

            /// <summary>
            /// 自动处理报警
            /// </summary>
            [Description("自动处理报警")]
            RemovedState = 3,

            /// <summary>
            /// 缓存发送网关状态
            /// </summary>
            [Description("缓存发送网关状态")]
            SendState = 4,

            /// <summary>
            /// 已派工
            /// </summary>
            [Description("已派工")]
            AlreadyDispatch = 5,

            /// <summary>
            /// 已下发整改通知
            /// </summary>
            [Description("已下发整改通知")]
            AlreadyRectifyNotice = 6,
        }
        public class Device 
        {
            public LastAlarm_AlarmStatus AlarmStatus { get; set; }

            public long ID { get; set; }
            public string DeviceNumber { get; set; }
        }

        public class Device2
        {
            public byte AlarmStatus { get; set; }

            public string DeviceNumber { get; set; }
            public string DeviceCode { get; set; }
        }


        static void Main(string[] args)
        {
            string path = "D://test.txt";
            string[] contents = new string[] {
                "阿巴阿巴阿巴，这里是文本1第一行",
                "阿巴阿巴阿巴，这里是文本2第二行" };
            File.AppendAllLines(path, new[] { contents[0] });
            //File.WriteAllLines(path, new[] { contents[0] + "\r\n" });
            Thread.Sleep(1000);
            File.AppendAllLines(path, new[] { contents[1] });
            //File.WriteAllLines(path, new[] { contents[1] + "\r\n" });

            //var datas = new List<Device>();
            //var min =datas.Select(s => s.ID).Min();
            //;

            //string jsonString = "{\"ID\":99,\"DeviceNumber\":\"10080074\",\"DeviceCode\":\"1008007431\",\"SignalLevel\":0,\"ProtocolType\":48,\"ItemCount\":1,\"DataVersion\":4,\"DataBuffer\":\"CDEwMDgwMDc0CjEwMDgwMDc0MzEAAAjcsh1s3TWAAAEAAAAAAA9DdgAAAAZSQ1hEATIAAAAAAAAAAA==\",\"DataTime\":\"2024-08-01T11:31:03\",\"LocalTime\":\"2023-09-14T20:50:42.007\"}";
            //var jObj = JsonConvert.DeserializeObject<Device>(jsonString);
            //;

            // 初始化RedisHelper对象
            // var csredis = new CSRedisClient("127.0.0.1:6379,defaultDatabase=0,prefix=_hetai_");
            // var csredis = new CSRedisClient("127.0.0.1:6379,defaultDatabase=0");
            //var csredis = new CSRedisClient("192.168.2.170:6379,defaultDatabase=0");
            //RedisHelper.Initialization(csredis);


            //const string mLastDeviceDataKey = "GWLastDeviceData";
            //var oldItem = RedisHelper.SScan(mLastDeviceDataKey, 0, pattern: $"*{100801754}*", count: int.MaxValue);

            //;

            //var setKey = "Set_Classrooms";

            //csredis.Del(setKey);
            //csredis.SAdd(setKey, new Device 
            //{
            //    AlarmStatus = LastAlarm_AlarmStatus.WaitingHandle,
            //});
            //var data = csredis.SMembers<Device>(setKey);
            //;



            //// 集合的遍历
            //foreach (var item in csredis.SMembers(setKey))
            //{
            //    Console.WriteLine($"集合成语：{item.ToString()}");
            //}





















            //var classrooms = new[]
            //{
            //    new Student{ Id = 1, Name = "张三", Age = 23 },
            //    new Student{ Id = 2, Name = "李四", Age = 26 },
            //    new Student{ Id = 3, Name = "王五", Age = 28 },
            //};
            //var extraStudent = new Student { Id = 4, Name = "刘六", Age = 30 };

            //var setKey = "Set_Classrooms";

            //csredis.SAdd(setKey, classrooms[0], classrooms[1], classrooms[1], classrooms[2]);

            //var datas = csredis.SMembers(setKey + "2111");

            //var item = csredis.SScan<Student>(setKey, 0, "*张三*");
            //;

            #region 字符串（string）
            /*
            var stringKey = "String_Classrooms";
            // 添加字符串键值对，添加一样的Key会被覆盖
            csredis.Set(stringKey + ":1", classrooms[0]);
            csredis.Set(stringKey + ":2", classrooms[1]);
            csredis.Set(stringKey + ":3", classrooms[2]);
            // 查询
            var string_zhangsan = csredis.Get<Student>(stringKey + ":1");

            // 移除
            csredis.Del(stringKey + ":2");

            // 数值操作
            var numKey = "Num_Key";
            csredis.Set(numKey, "24");

            // value += 5
            csredis.IncrBy(numKey, 5);
            // output -> 29

            // value -= 10
            csredis.IncrBy(numKey, -10);
            // output -> 19

            // 字节串操作
            var stringKey2 = "string-key";
            csredis.Set(stringKey2, "hello ");

            // 在指定key的value末尾追加字符串
            csredis.Append(stringKey2, "world");
            // output -> "hello world"

            // 获取从指定范围所有字符构成的子串（start:3,end:7）
            csredis.GetRange("string-key", 3, 7);
            // output ->  "lo wo"

            // 用新字符串从指定位置覆写原value（index:4）
            csredis.SetRange("string-key", 4, "aa");
            // output -> "hellaaword"
            */
            #endregion

            #region 列表（list）
            /*
            var listKey = "List_Classrooms";
            // 从右端推入元素
            csredis.RPush<Student>(listKey, classrooms[0], classrooms[1], classrooms[2]);
            // 从右端弹出元素
            csredis.RPop(listKey);
            // 从左端弹入元素
            csredis.LPush(listKey, extraStudent);
            // 从左端弹出元素
            csredis.LPop(listKey);

            // 遍历链表元素
            foreach (var item in csredis.LRange<Student>(listKey, 0, -1)) 
            {
                Console.WriteLine(item);
            }

            // 按索引值获取元素（当索引值）
            Console.WriteLine($"{csredis.LIndex<Student>(listKey, 1)}");

            // 修剪指定范围内的元素(Start:4, end:10)
            csredis.LTrim(listKey, 4, 10);

            // 将my-list最后一个元素弹出并压入another-list头部
            csredis.RPopLPush(listKey, "another-list");
            */
            #endregion

            #region 集合（set）
            /*
            var setKey = "Set_Classrooms";

            csredis.SAdd(setKey, classrooms[0], classrooms[1], classrooms[1], classrooms[2]);

            // 集合的遍历
            foreach (var item in csredis.SMembers(setKey)) 
            {
                Console.WriteLine($"集合成语：{item.ToString()}");
            }

            // 判断元素是否存在
            Console.WriteLine($"第0个元素是否存在：{csredis.SIsMember(setKey, classrooms[0])}");
            // output -> True

            // 移除元素
            csredis.SRem(setKey, classrooms[2]);
            Console.WriteLine($"第2个元素是否存在：{csredis.SIsMember(setKey, classrooms[2])}");

            // 随机移除一个元素
            csredis.SPop(setKey);

            csredis.SAdd("set-a", "item1", "item2", "item3", "item4", "item5");
            csredis.SAdd("set-b", "item2", "item5", "item6", "item7");

            // 差集
            csredis.SDiff("set-a", "set-b");
            // output -> "item1", "item3","item4"

            // 交集
            csredis.SInter("set-a", "set-b");
            // output -> "item2","item5"

            // 并集
            csredis.SUnion("set-a", "set-b");
            // output -> "item1","item2","item3","item4","item5","item6","item7"
            */
            #endregion

            #region 散列（Hashmap）
            /*
            // 向散列添加元素
            csredis.HSet("ArticleID:10001", "Title", "了解简单的Redis数据结构");
            csredis.HSet("ArticleID:10001", "Author", "xscape");
            csredis.HSet("ArticleID:10001", "PublishTime", "2019-01-01");

            // 根据Key获取散列中的元素
            csredis.HGet("ArticleID:10001", "Title");

            // 获取散列中的所有元素
            foreach (var item in csredis.HGetAll("ArticleID:10001")) 
            {
                Console.WriteLine(item.Value);
            }

            //HMGet和HMSet是他们的多参数版本，一次可以处理多个键值对
            var keys = new string[] { "Title", "Author", "publishTime" };
            csredis.HMGet("ArticleID:10001", keys);

            //和处理字符串一样，我们也可以对散列中的值进行自增、自减操作，原理同字符串是一样的
            csredis.HSet("ArticleID:10001", "votes", "257");
            csredis.HIncrBy("ArticleID:10001", "votes", 40);
            // output -> 297
            */
            #endregion

            #region 有序集合（ZSet）
            /*
            // 向有序集合添加元素
            csredis.ZAdd("Quiz", (79, "Math"));
            csredis.ZAdd("Quiz", (98, "English"));
            csredis.ZAdd("Quiz", (87, "Algorithm"));
            csredis.ZAdd("Quiz", (84, "Database"));
            csredis.ZAdd("Quiz", (59, "Operation System"));

            // 返回集合中的元素数量
            csredis.ZCard("Quiz");

            // 获取集合中指定范围(90~100)的元素集合
            var ZRangeByScoreResult = csredis.ZRangeByScore("Quiz", 90, 100);

            // 获取集合所有元素并升序排序
            var ZRangeWithScoresResult = csredis.ZRangeWithScores("Quiz", 0, -1);

            // 移除集合中的元素
            csredis.ZRem("Quiz", "Math");

            // Key的过期
            csredis.Set("MyKey", "hello,world");
            Console.WriteLine(csredis.Get("MyKey"));
            // output -> "hello,world"

            csredis.Expire("MyKey", 5); // key在5秒后过期，也可以使用ExpireAt方法让它在指定时间自动过期


            Thread.Sleep(6000); // 线程暂停6秒
            Console.WriteLine(csredis.Get("MyKey"));
            // output -> ""
            */
            #endregion

            #region 订阅发布
            /*
            // 普通订阅
            csredis.Subscribe(
                ("chan1", msg => Console.WriteLine(msg.Body)),
                ("chan2", msg => Console.WriteLine(msg.Body))
            );
            // 模式订阅
            csredis.PSubscribe(new[] { "chan*", "test*", "*test001", "test*002" }, msg =>
            {
                Console.WriteLine($"PSUB  {msg.MessageId}:{msg.Body}  {msg.Pattern}: chan:{msg.Channel}");
            });
            // 模式订阅已经解决的难题：
            // 1. 分区的节点匹配规则，导致通配符最大可能匹配全部节点，所以全部节点都要订阅
            // 2. 本组 "test*", "*test001", "test*002" 订阅全部节点时，需要解决同一条消息不可执行多次

            // 发布
            csredis.Publish("chan1", "123123123");
            // 无论是分区或普通模式，csredis.Publish都可以正常通讯
            */
            #endregion

            #region 缓存壳

            #endregion

            #region 管道
            /*
            var ret1 = csredis.StartPipe().Set("a", 1).Get("a").EndPipe();
            var ret2 = csredis.StartPipe(p => p.Set("a", "1").Get("a"));

            var ret3 = csredis.StartPipe().Get("b").Get("a").Get("a").EndPipe();
            */
            #endregion




            #region 0.通用指令
            /*
            // 查找所有分区节点中符合给定模式（pattern）的key
            string[] keyAll = RedisHelper.Keys("*");

            // 以秒为单位，返回给定 key 的剩余生成时间
            long ttl1 = RedisHelper.Ttl("keyString1");

            // 用于在 key 存在时删除 key
            long del1 = RedisHelper.Del("keyString1");

            // 检查给定 key 是否存在
            bool isExists1 = RedisHelper.Exists("keyString1");

            // 为给定 key 设置过期时间
            bool isExpire1 = RedisHelper.Expire("keyString1", 100);

            // 为给定 key 设置过期时间
            RedisHelper.ExpireAt("keyString1", new DateTime(2021, 6, 11, 16, 0, 0));
            */
            #endregion

            #region 1. String(字符串)
            /*
            #region 1.1. 简单操作
            // 设置指定 key 值，默认不过期
            bool set_string1 = RedisHelper.Set("keyString_String1", "测试值1");

            // 设置指定 key 值，并设置过期时间(单位：秒)
            bool set_string2 = RedisHelper.Set("keyString_String2", "测试值2", 1);

            // 获取指定 key 的值，不存在的 key，值返回null
            string get_string1 = RedisHelper.Get("keyString_String1");

            // 获取指定 key 的值，不存在的 key，或者指定的 key，不是int型，则返回int类型的默认值0
            int get_int1 = RedisHelper.Get<int>("keyString_String1");
            #endregion

            #region 自增，自减操作
            bool set_int1 = RedisHelper.Set("keyString_Num1", "23");

            // 将key所存储的值加上指定的增量值(increment)
            long incrBy1 = RedisHelper.IncrBy("keyString_Num1", 2); // #25

            // 将key所存储存的值加上指定的增量值（increment），负数就是减量值
            long incrBy2 = RedisHelper.IncrBy("keyString_Num1", -1); // #24
            #endregion

            #region 追加文本
            bool set_append1 = RedisHelper.Set("keyString_Append1", "qaz", 30);

            // 将指定的 value 追加到该 key 原来值（value）的末尾
            long append1 = RedisHelper.Append("keyString_Append1", "wsx"); // #6 结果：key 中字符串的长度
            #endregion
            */
            #endregion



            #region 2. Hash(哈希)
            /*
            // 将哈希表 key 中的字段 field的值设为value
            bool set_hash_user1_uname = RedisHelper.HSet("User:10001", "uname", "gongyg"); // 冒号的作用相当于创建一个文件夹
            bool set_hash_user1_upwd = RedisHelper.HSet("User:10001", "upassword", "123456");
            bool set_hash_user1_uid = RedisHelper.HSet("User:10001", "uid", "12");

            // 获取存储在哈希表中指定字段的值
            */
            #endregion
        }
    }

    public class Student
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public int Age { get; set; }

        public override string ToString()
        {
            return $"Id:{Id},Age:{Age},Name:{Name}";
        }
    }

    /*
    public class Student : IEquatable<Student>
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public int Age { get; set; }

        public bool Equals(Student? other)
        {
            if (other == null)
            {
                return false;
            }
            return Id == other.Id;
        }

        public override int GetHashCode()
        {
            return Id;
        }

        public override string ToString()
        {
            return $"Id:{Id},Age:{Age},Name:{Name}";
        }
    }
    */
        }
